#include <dm/os/db/resultset_pg.hpp>

namespace dm{
namespace os{

CResultSetPg::CResultSetPg():m_rst(NULL){

}

CResultSetPg::~CResultSetPg(){
	if( m_rst!=NULL )
		PQclear(m_rst);
}

int CResultSetPg::size()const{
	if( m_rst!=NULL )
		return PQntuples(m_rst);

	return 0;
}

bool CResultSetPg::next(){
	if( m_rst!=NULL ){
        if( m_r==size() )
            return false;

   ++m_r;
   	   if( m_r==size() )
   		   return false;
        return true;
 }

	return false;
}

void CResultSetPg::reset(){
	m_r = -1;
}

template<typename T>
inline T getValue(const PGresult* rs,int r,int c){
    return *((T*)PQgetvalue(rs,r,c));
}

template<typename T>
inline T getValue(const PGresult* rs,int r,const char* name ){
    return getValue<T>(rs,r,PQfnumber(rs,name));
}

bool CResultSetPg::asBool( int col )const{
	if( PQfformat(m_rst, col)!=0 )
		return getValue<bool>(m_rst,m_r,col);
	else{
		const char* v = PQgetvalue(m_rst, m_r, col);
		return 't'==v[0] || 'T'==v[0];
	}
}

bool CResultSetPg::asBool( const char* col )const{
	return asBool(PQfnumber(m_rst, col));
}

int CResultSetPg::asInt( int col )const{
	if( PQfformat(m_rst, col)!=0 )
		return getValue<int>(m_rst,m_r,col);
	else
		return atoi(PQgetvalue(m_rst, m_r, col));
}

int CResultSetPg::asInt( const char* col )const{
	return asInt(PQfnumber(m_rst, col));
}

dm::uint CResultSetPg::asUint( int col )const{
	if( PQfformat(m_rst, col)!=0 )
		return getValue<dm::uint>(m_rst,m_r,col);
	else
		return atoi(PQgetvalue(m_rst, m_r, col));
}

dm::uint CResultSetPg::asUint( const char* col )const{
	return asUint(PQfnumber(m_rst, col));
}

dm::int64 CResultSetPg::asInt64( int col )const{
	if( PQfformat(m_rst, col)!=0 )
		return getValue<dm::int64>(m_rst,m_r,col);
	else
		return atol(PQgetvalue(m_rst, m_r, col));
}

dm::int64 CResultSetPg::asInt64( const char* col )const{
	return asInt64(PQfnumber(m_rst, col));
}

double CResultSetPg::asDouble( int col )const{
	if( PQfformat(m_rst, col)!=0 )
		return getValue<double>(m_rst,m_r,col);
	else
		return atof(PQgetvalue(m_rst, m_r, col));
}

double CResultSetPg::asDouble( const char* col )const{
	return asDouble(PQfnumber(m_rst, col));
}

std::string CResultSetPg::asString( int col )const{
	return PQgetvalue(m_rst,m_r,col);
}

std::string CResultSetPg::asString( const char* col )const{
	return PQgetvalue(m_rst,m_r,PQfnumber(m_rst,col));
}

bool CResultSetPg::isNull( int col )const{
	return PQgetisnull(m_rst,m_r,col);
}

bool CResultSetPg::isNull( const char* col )const{
	return PQgetisnull(m_rst,m_r,PQfnumber(m_rst,col));
}

int CResultSetPg::columnSize()const{
	if( m_rst!=NULL ){
		return PQnfields(m_rst);
	}

	return 0;
}

std::string CResultSetPg::valueString( int col )const{
	if( m_rst!=NULL ){
    }
	return "";
}

std::string CResultSetPg::valueString( const char* col )const{
	return valueString(PQfnumber(m_rst,col));
}

void CResultSetPg::free(){
	if( m_rst!=NULL ){
        PQclear(m_rst);
        m_rst = NULL;
    }
}

}
}
